home *** CD-ROM | disk | FTP | other *** search
/ Aminet 50 / Aminet 50 (2002)(GTI - Schatztruhe)[!][Aug 2002].iso / Aminet / text / edit / tecoc-146.lha / pg.rno < prev    next >
Text File  |  1991-07-05  |  37KB  |  772 lines

  1. .!
  2. .!    This file is the source for file PG.MEM.  Run this file through
  3. .!  VAX RUNOFF to produce PG.MEM.
  4. .!
  5. .AUTOPARAGRAPH
  6. .LEFT MARGIN 0
  7. .RIGHT MARGIN 75
  8.  
  9. .CENTER
  10. TECO-C
  11. .SKIP
  12. .CENTER
  13. Programmer's Guide
  14. .CENTER
  15. (last updated February 18, 1991 to reflect TECO-C version 140)
  16.  
  17. .HEADER LEVEL 1 Introduction
  18.  
  19.     These notes apply to TECOC version 135, which runs under
  20. VAX/VMS, MS-DOS, and Unix (SunOS, which is BSD).  See file
  21. AAREADME.TXT for the specifics of operating system and compilers
  22. which have been used.
  23.     TECO-C is meant to be a complete implementation of TECO as
  24. defined by the Standard TECO User's Guide and Language Reference
  25. Manual, (in file TECO.DOC).  It was written so that author could move
  26. to many machines without knowing many editors.
  27.  
  28. .HEADER LEVEL 1 Compiling and Linking
  29.  
  30.     Conditional compilation directives are used to build TECO-C
  31. correctly for different environments.  Identifiers automatically
  32. defined by thedifferent compilers are used.  Some identifiers defined
  33. in file ZPORT.H control whether video support or extra debugging code
  34. is included.  See "VIDEO" and "DEBUGGING".
  35. ex    Files are provided which "build" TECO-C in various environments.
  36. See file AAREADME.TXT for details.
  37.  
  38. .HEADER LEVEL 1 Running TECO-C
  39.     
  40.     When you run TECO, the command line used to invoke TECO is
  41. parsed for an input/out file name and several optional switches.
  42. TECO-11 parses the command line using a TECO macro imbedded in the
  43. program.  TECO-C does the same thing.  Actually, the imbedded macro
  44. used to parse the command line was stolen from TECO-11.  I commented
  45. it and then modified it to repair minor inconsistencies.  Use of
  46. TECO-11's macro makes TECO-C invokation identical to TECO-11's, even
  47. responding to "make love" with "Not war?".
  48.     The macro is in file CLPARS.TES.  The compressed version (no
  49. comments or whitespace) is in file CLPARS.TEC.  The GENCLP program
  50. converts CLPARS.TEC into CLPARS.H,  an include file suitable for
  51. compiling into TECO-C.
  52.  
  53. .HEADER LEVEL 1 Code Conventions
  54.  
  55.     The code is not modular.  Communication between almost all
  56. functions is through global variables, not argument lists.  There is a
  57. reason: the nature of the basic parsing algorithm is to use the
  58. characters in the command string as indices into a table of functions.
  59. This makes for very fast command parsing, but it means that all the
  60. functions have to modify global values, because no arguments are
  61. passed in.  In other words, there were going to be 130 or un-modular
  62. functions anyway, so I gave up on modularity.  This explanation does
  63. not explain some of the complications in the search code, like the
  64. global variable SrcTyp.  Oh, well.
  65.     Here's a brief list of some of the conventions followed by the
  66. code:
  67.  
  68. .LIST
  69.  
  70. .LIST ELEMENT
  71. TECO-C is portable, so some convention was needed to separate portable
  72. code from system-dependent code.  There is one file containing the
  73. system-dependent code for each platform TECO-C supports.  These files
  74. have names that start with a "Z": ZVMS.C, ZMSDOS.C and ZUNIX.C.
  75. .SKIP
  76. All the system-dependent functions in those files start with a "Z".
  77. For example, the function that allocates memory is called ZAlloc.  A
  78. VMS version of ZAlloc can be found in ZVMS.C, and an MS-DOS version
  79. can be found in ZMSDOS.C.
  80. .SKIP
  81. An extra file called ZUNKN.C exists to help efforts to port TECO-C to
  82. a new environment.  This file contains stubs for all the
  83. system-dependent functions.
  84.  
  85. .LIST ELEMENT
  86. All system-independent global variables are declared alphabetically in
  87. file TECOC.C.  They are defined in DEFEXT.H, which is included by all
  88. modules.
  89.  
  90. .LIST ELEMENT
  91. File TECOC.H contains the "global" definitions, including those for
  92. msot structures.
  93.  
  94. .LIST ELEMENT
  95. Variables and functions are defined using the portability identifiers
  96. defined in the ZPORT.H file.  Functions which do not return a value
  97. are defined as VOID.  TECO-C should compile and link on different
  98. machines by changing only the environment definitions in the ZPORT.H
  99. file.
  100.  
  101. .LIST ELEMENT
  102.  
  103. At one time, every function was in a file with the same name as the
  104. function.  This made it easy to find the code for a function.  The
  105. problem was that some groups of functions use data not needed by the
  106. other functions.  This was especially true of the system-dependent
  107. functions.  Also, some functions were called only by one other
  108. function, so it made sense for them to be in the same module as the
  109. caller and be made "static".  So now, most functions are in a file
  110. named the same as the function, with the following exceptions:
  111.  
  112. .LIST
  113. .LIST ELEMENT
  114. All the "Z" functions are in are in the "Z" file for the given system.
  115. .LIST ELEMENT
  116. The conditionally-compiled functions (ZCpyBl in ZINIT.C, the "Dbg"
  117. functions at the bottom of TECOC.C, the "v" functions in EXEW.C)
  118. aren't in their own files.  If they were, then the command
  119. procedures/makefiles that compile the files would need to contain
  120. logic to conditionally compile the files.
  121. .LIST ELEMENT
  122. The functions for the "E" and "F" commands are in EXEE.C and EXEF.C,
  123. respectively.  So if you want to find function ExeEX, don't look for a
  124. file named EXEEX.C.
  125. .END LIST
  126.  
  127. .LIST ELEMENT
  128. Symbols are 6 characters long or less.  The way I remember it, this
  129. was caused by the first system I wrote TECOC for: CP/M-68k, which had
  130. a limit of 8 characters for file names.  The last two characters had
  131. to be ".C", so 6 characters were left for the file name.  Since the
  132. file name was the same as the function it contained, functions were
  133. limited to 6 characters in length.  When I saw how nicely the function
  134. declarations looked (they fit in one tab slot), I used 6 characters
  135. for other symbols too.
  136. .SKIP
  137. I've since been told that CP/M-68k has 8-character file names followed
  138. by 3-character file types, so CP/M-68k can't be blamed.  So shoot me.
  139. .SKIP
  140. This standard has prevented problems from occurring with compilers
  141. that don't support very many characters of uniqueness.
  142. .SKIP
  143. In order to make up for the resultant cryptic names, upper and lower
  144. case are mixed.  An uppercase letter indicates a new word.  For
  145. example, "EBfEnd" stands for "Edit Buffer End".  If you need to know
  146. what a variable name means, look at the definition of the variable in
  147. DEFEXT.H.  The expanded version of the abbreviated name appears in the
  148. comment on the same line as the variable definition.  A detailed
  149. description can be found with the declaration of the variable in
  150. TECOC.C.
  151. .SKIP
  152. The limit of 6 letters in variable names is relaxed in
  153. system-dependent code.
  154.  
  155. .LIST ELEMENT
  156. Variable and function names follow patterns where possible.  For
  157. instance, "EBfBeg" and "EBfEnd" are the beginning and end of the edit
  158. buffer.  If you see a variable named "BBfBeg", you can assume that it
  159. is the beginning of some other buffer, and that a "BBfEnd" exists
  160. which is the end of that buffer.
  161.  
  162. .LIST ELEMENT
  163. Character strings are usually represented in C by a pointer to a
  164. sequences of bytes terminated with a null character.  I didn't do that
  165. in TECO-C because I thought it was too inefficient.  To get the length
  166. of a string, you have to count characters.  Most strings in TECO-C are
  167. therefore represented by two pointers, on to the first character and
  168. one to the character following the last character.  With this
  169. representation, it's easy to add characters to a string and trivial to
  170. get the length.
  171.  
  172. .LIST ELEMENT
  173. Each file has a consistent format,  which is:
  174. .SKIP
  175. .LIST 0
  176. .LIST ELEMENT;a comment describing the function
  177. .LIST ELEMENT;include directives
  178. .LIST ELEMENT;the function declaration
  179. .LIST ELEMENT;local variable definitions, in alphabetical order
  180. .LIST ELEMENT;code
  181. .END LIST 0
  182. .END LIST
  183.  
  184. .HEADER LEVEL 1 Top Level Execution and Command Parsing
  185.  
  186.     The top level code for TECO-C is contained in file TECOC.C.
  187. It is very simple: after initializing, a loop is entered which reads a
  188. command string from the user, executes it, and loops back to read
  189. another command string.  If the user executes a command which causes
  190. TECO-C to exit, the program is exited directly via a call to the
  191. TAbort function.  TECO-C never exits by "falling out the bottom" of
  192. the main function.
  193.     After a command string is read, the ExeCSt function is called
  194. to execute the command string.  ExeCSt contains the top-level parsing
  195. code.  The parse is trivial: each command character is used as an
  196. index into a table of functions.  The table contains one entry for
  197. each of the 128 possible characters.  Each function is responsible for
  198. "consuming" its command so that when it returns, the command string
  199. pointer points to the next command.
  200.  
  201. .HEADER LEVEL 2 Error handling
  202.     When an error is detected, an error message is displayed at
  203. the point that the error is detected, and the function in which the
  204. error was detected returns a FAILURE status to its caller.  Almost
  205. always, the caller returns a FAILURE status to it's caller, which
  206. returns a FAILURE status to it's caller, etc.  When a FAILURE status
  207. is returned to the main command string parser, parsing of the command
  208. string stops and the user is prompted for a new command string.
  209.     This style tends to cause all function calls to follow the
  210. same form, which is
  211. .SKIP
  212. .LITERAL
  213.                     if (function() == FAILURE)
  214.                             return(FAILURE);
  215. .END LITERAL
  216.     Things get more complicated in the system-dependent code (in
  217. the files with names that start with a "Z").  I extended TECO's error
  218. reporting slightly to allow the user to see the operating system's
  219. reason for an error, as this is often useful.  For example, under
  220. VAX/VMS there are many reasons why an attempt to create an output file
  221. might fail.  They include: errors in file name syntax, destination
  222. directory non-existence, file protection violations or disk quota
  223. violation.  In order to supply enough information to the user, TECO-C
  224. outputs multiple-line error messages when a system error occurs.
  225.     Multiple-line error messages contain one line that describes
  226. the operating system's perception of the error and one line that
  227. describe's TECO's perception of the error.  For instance, if a user of
  228. VAX/VMS does a "EW[abc]test.txt$$" command when the directory [abc]
  229. does not exist, the error message generated by TECO-C is:
  230. .SKIP
  231. .LITERAL
  232.             ?SYS   %RMS-F-DNF, directory not found
  233.             ?UFO   unable to open file "[abc]test.txt" for output
  234. .END LITERAL
  235.     System errors are therefore reported in a system-dependent
  236. fashion, using whatever messages the operating system can supply.
  237. Under VAX/VMS, the system service $GETMSG provides human-readable
  238. messages that TECO-C can use in the "SYS" part of the error message.
  239. Under UNIX, sys_errlist[error] is a pointer to these messages.
  240.     There is another way in which error reporting in the
  241. system-dependent code is tricky.  Under VAX/VMS, some system calls may
  242. return a code that is "successful" but contains extra information.
  243. For instance, when a user has set his directories so that only a
  244. limited number of versions of a file can exist, RMS will automatically
  245. purge the oldest version of the file when the user creates a file.
  246. This only happens if the newly created file would cause too many
  247. versions of the file to exist.  When this happens, the VMS service
  248. returns a FILEPURGED status, which is successful.  TECO-C informs the
  249. user about these things by displaying the message in brackets.
  250.  
  251. .HEADER LEVEL 2 Command modifiers (CmdMod)
  252.     Command parsing is complicated by command modifiers and
  253. numeric arguments, which may precede some commands.  These are
  254. implemented in a way that maintains the basic "jump table" idea.  For
  255. instance, when an at-sign (@) modifier is encountered in a command
  256. string, the at-sign command function (ExeAtS) is called.  The only
  257. thing ExeAtS does is set a flag indicating that an at-sign has been
  258. encountered.  Commands which are affected by an at-sign modifier check
  259. this flag and behave accordingly.
  260.     The flags which indicate command modifiers are contained in
  261. global variable CmdMod.  A bit in CmdMod is reserved for each command
  262. modifier.  The modifiers are "@", ":" and "::".  Of course, once the
  263. flag has been set, it must be cleared.  With this parsing algorithm,
  264. the only way to do that is to make every command function explicitly
  265. reset CmdMod before a successful return.  This is not too bad:
  266. clearing all the flags in CmdMod is done with one statement: "CmdMod =
  267. '_\0';".
  268.     For numeric arguments to commands, an expression stack is used
  269. (see Stacks).  The EstTop variable is the pointer to the top of the
  270. expression stack.  Commands which handle numeric arguments check
  271. EStTop to see if the expression stack contains a value.
  272.     A special case of numeric arguments is "m,n".  The "m" part is
  273. encountered and causes the value to be pushed onto the expression
  274. stack.  The comma causes the ExeCom function to move the value into a
  275. special "m-argument" global variable (MArgmt), clear the expression
  276. stack and set another flag in CmdMod indicating that the "m" part of
  277. an "m,n" pair is defined.  Then the "n" is encountered and pushed onto
  278. the stack.  Commands which can take "m,n" pairs check the flag in
  279. CmdMod.
  280.     To summarize, CmdMod and EStTop are variables which describe
  281. the context of a command.  Each command function tests these variables
  282. to see if it was preceded by modifiers or numbers.  For this to work,
  283. it is important that the expression stack and the flags in CmdMod are
  284. cleared at the right times.  It is the responsibility of each command
  285. function to leave CmdMod and EStTop with the proper values before
  286. successfully returning.  The rules are:
  287. .LIST
  288. .LIST ELEMENT
  289. If the command function is returning FAILURE, don't worry about
  290. clearing CmdMod or EStTop.  They will be cleared before the next
  291. command string is executed.
  292. .LIST ELEMENT
  293. If the command function leaves a value on the expression stack, do not
  294. clear EStTop before returning SUCCESS.  If the command calls GetNmA,
  295. do not clear EStTop, as GetNmA does it for you.  Otherwise, clear
  296. EStTop before returning SUCCESS.
  297. .LIST ELEMENT
  298. Clear CmdMod unless the command function sets flags or needs to leave
  299. them alone.  ExeDgt, for example,  handles digit strings and doesn't
  300. clear CmdMod because the MARGIS bit may be set.
  301. .END LIST
  302.  
  303. .HEADER LEVEL 1 Searching
  304.     The search algorithm in TECO-C is complex.  The war between
  305. the desire for a fast search and the need to handle all the features
  306. of TECO'ssearch commands has produced code which can be a real pain to
  307. follow.  This section attempts to explain how things got the way they
  308. are.  The code is explained in a bottom-up fashion, to follow the way
  309. it evolved in the author's twisted mind.
  310.     The basic search idea is to scan a contiguous edit buffer for
  311. a search string.  The steps are:
  312. .LIST
  313. .LIST ELEMENT
  314. Search the edit buffer for the first character in the search string.
  315. If you reach the end of the edit buffer without matching, the search
  316. fails.
  317. .LIST ELEMENT
  318. When the first character of the search string matches a character in
  319. the edit buffer, try to match successive characters in the search
  320. string with the characters which follow the found character in the
  321. edit buffer.  If they all match, the search succeeds.  If one doesn't,
  322. go back to step 1.
  323. .END LIST
  324.     This is basically what TECO-C does.  The features of TECO's
  325. search commands has buried these steps deep within some confusing
  326. code.
  327.  
  328.     The first complication is introduced by pattern matching
  329. characters.  TECO has 17 "match constructs", whiceh are indicated in
  330. the search string by the special characters _^X, _^S, _^N and _^Ex
  331. where "x" can be several other characters.  For instance, a _^X in the
  332. search string means that any character is to be accepted as a match in
  333. place of the _^X.  Characters other than the match constructs
  334. represent themselves.  An example: the search string "a_^Xb" contains
  335. 3 match constructs: a, _^X and b.
  336.  
  337.     TECO also supports forward or backward searching.  When
  338. searching backwards, only the search for the first match construct in
  339. the search string is done in a backwards direction.  When the
  340. character is found, the characters following it are compared in a
  341. forward direction to the edit buffer characters.  This means that once
  342. the first match construct has been found, a single piece of code can
  343. be used to compare successive characters in the search string with
  344. successive characters in the edit buffer, regardless of whether the
  345. search is forwards or backwards.
  346.  
  347.     Adding these new features,  the new description of searching is:
  348. .LIST
  349. .LIST ELEMENT
  350. Search the edit buffer forwards or backwards for a character which
  351. matches the first match construct in the search string.  If you reach
  352. the end of the edit buffer without matching, the search fails.
  353. .LIST ELEMENT
  354. When the first match construct of the search string matches a
  355. character in the edit buffer, try to match successive match constructs
  356. in the search string with the characters which follow the found
  357. character in the edit buffer.  If they all match, the search succeeds.
  358. If one doesn't, go back to step 1.
  359. .END LIST
  360.     To begin a description of which routines implement the above
  361. steps, and in order to have a reference for later discussion, the
  362. following hierarchy chart of "who calls who" is presented.
  363. .SKIP 2
  364. .TEST PAGE 25
  365. .LITERAL
  366.  ExeEUn ExeFB ExeFC ExeFD ExeFK ExeFN ExeFS ExeFUn ExeN ExeS ExeUnd
  367.     |     |     |     |     |     |     |     |      |    |    |
  368.     |     |     |     |     |     |     |     |      |    |    |
  369.     ------------------------------------------------------------
  370.                                   |
  371.                                   V
  372.                                 Search
  373.                                   |
  374.                                   V
  375.                                 SrcLop
  376.                                   |
  377.                                   V
  378.                                 SSerch
  379.                                |  |  |
  380.                         +------+  |  +------+
  381.                  +---+  |         |         |  +---+
  382.                  |   V  V         |         V  V   |
  383.                  |  ZFrSrc        |        BakSrc  |
  384.                  |   |  |         |         |  |   |
  385.                  +---+  |         |         |  +---+
  386.                         +------+  |  +------+
  387.                                V  V  V
  388.                                 CMatch  <--+
  389.                                   |        |
  390.                                   +--------+
  391. .END LITERAL
  392. .SKIP
  393.     At the top are the functions that implement search commands
  394. (E__, FB, FC, FD, FK, FN, FS, F__, N, S and __).  All of these functions
  395. call the main search function: Search.
  396.     At the lower level are the functions which implement steps 1
  397. and 2 described above. ZFrSrc searches forwards in the edit buffer for
  398. characters which match the first character in the search string.
  399. BakSrc does the same thing, but searches backwards.  SSerch calls one
  400. of these two functions and then executes a loop which calls CMatch to
  401. compare successive match constructs in the search string to characters
  402. following the found character in the edit buffer.  The reason that
  403. ZFrSrc, BakSrc and CMatch call themselves is to handle some of the
  404. more esoteric match constructs.
  405.     Case dependence in TECO is controlled by the search mode
  406. flag (see the _^X command).  The variable SMFlag holds the value of
  407. the search mode flag, and is used by ZFrSrc, BakSrc and CMatch.
  408.     One final point to help confuse things: ZFrSrc is
  409. system-dependent.  It contains a VAX/VMS-specific version which uses
  410. the LIB$SCANC run-time library routine to access the SCANC
  411. instruction.  The SCANC instruction looks like it was designed to
  412. handle TECO's match constructs.  I couldn't resist using it, but it
  413. was a mistake, as it needlessly complicates an already messy
  414. algorithm.  I have decided to remove the VMS-specific code some time
  415. in the future.
  416.     Further complications of the search algorithm arise because of
  417. the following capabilities of TECO searches:
  418. .LIST
  419. .LIST ELEMENT
  420. If there is no text argument,  use the previous search argument.
  421. .LIST ELEMENT
  422. If colon modified,  return success/failure and no error message
  423. .LIST ELEMENT
  424. If the search fails and we're in a loop and a semicolon follows
  425. the search command,  exit the loop without displaying an error message.
  426. .LIST ELEMENT
  427. Handle optional repeat counts
  428. .LIST ELEMENT
  429. If the ES flag is non-zero,  verify the search based on the value of the flag.
  430. .LIST ELEMENT
  431. If bit 64 of the ED flag is set,  move dot by one on multiple searches.
  432. .LIST ELEMENT
  433. If bit 16 of the ED flag is set,  don't move after a failing search.
  434. .LIST ELEMENT
  435. Be fast.
  436. .END LIST
  437.  
  438. .HEADER LEVEL 1 Memory Management
  439.  
  440. .HEADER LEVEL 2 The edit buffer and input buffer
  441.     TECO-C is based on TECO-11,  but it uses a different form of edit
  442. buffer memory management.  Here's why.
  443.     The edit buffer in TECO-11 is implemented as a continuous
  444. block of memory.  This allows rapid movement through the edit buffer
  445. (by just maintaining a pointer to the current spot) and makes searches
  446. very straightforward.  Insertion and deletion of text is expensive,
  447. because each insertion or deletion requires moving the text following
  448. the spot where the insertion or deletion occurs in order to maintain a
  449. continuous block of memory.  This gets to be a real pain when a video
  450. editing capability is added to TECO, because in video mode text is
  451. added/deleted one character at a time very rapidly.
  452.     TECO-C uses a edit buffer gap scheme.  The edit buffer
  453. occupies a continuous piece of memory, but there is a gap at the
  454. "current spot" in the edit buffer.  When the user moves around the
  455. edit buffer, the gap is moved by shuffling text from one side of the
  456. gap to the other.  This means that moving around the text buffer is
  457. slower than for TECO-11's scheme, but text insertion and deletion is
  458. very fast.  Searches are still fast because most searches start at the
  459. current spot and go forwards or backwards, so a continuous piece of
  460. memory is searched.  In the future, when some kind of video mode is
  461. added, insertion and deletion one-character-at-a-time will be fast
  462. using the gap scheme.
  463.     The variables that maintain pointers to the edit buffer and
  464. the gap within the buffer can be confusing, so here's some examples.
  465. Suppose that 10000 bytes are allocated for the edit buffer when TECO-C
  466. is initialized.  Suppose the allocated memory starts at address 3000.
  467. .SKIP
  468. .TEST PAGE 6
  469. .LITERAL
  470.     Empty edit buffer (the gap spans the whole edit buffer):
  471.  
  472.         EBfBeg = 3000        (edit buffer beginning)
  473.         GapBeg = 3000        (gap beginning)
  474.         GapEnd = 13000        (gap end)
  475.         EBfEnd = 13000        (edit buffer end)
  476. .END LITERAL
  477. .TEST PAGE 10
  478. .LITERAL
  479.  
  480.     Buffer contains "test",  character pointer is before the first 't':
  481.  
  482.         EBfBeg = 3000        (edit buffer beginning)
  483.         GapBeg = 3000        (gap beginning)
  484.         GapEnd = 12996        (gap end)
  485.              12997    't'
  486.              12998    'e'
  487.              12999    's'
  488.         EBfEnd = 13000    't'    (edit buffer end)
  489. .END LITERAL
  490. .TEST PAGE 10
  491. .LITERAL
  492.  
  493.  
  494.     Buffer contains "test",  character pointer is after the last 't':
  495.  
  496.         EBfBeg = 3000    't'    (edit buffer beginning)
  497.              3001    'e'
  498.              3002    's'
  499.              3003    't'
  500.         GapBeg = 3004        (gap beginning)
  501.         GapEnd = 13000        (gap end)
  502.         EBfEnd = 13000        (edit buffer end)
  503. .END LITERAL
  504. .TEST PAGE 10
  505. .LITERAL
  506.  
  507.  
  508.     Buffer contains "test",  character pointer is after the 'e':
  509.  
  510.         EBfBeg = 3000    't'    (edit buffer beginning)
  511.              3001    'e'
  512.         GapBeg = 3002        (gap beginning)
  513.         GapEnd = 12998        (gap end)
  514.              12999    's'
  515.         EBfEnd = 13000    't'    (edit buffer end)
  516. .END LITERAL
  517.     When an insertion command is executed, the text is inserted
  518. starting at GapBeg.  When a deletion command is executed, GapEnd is
  519. incremented for a forward delete or GapBeg is decremented for a
  520. backwards delete.  When the character pointer is moved forwards, the
  521. gap is moved forwards by copying text from the end of the gap to the
  522. beginning.  When the character pointer is moved backwards, the gap is
  523. moved backwards by copying text from the the area just before the gap
  524. to the area at the end of the gap.
  525.     There are a few messy cases, such as when a bounded search is
  526. executed and the bounded text area includes the edit buffer gap.  In
  527. this case, the gap is temporarily moved so that the search can proceed
  528. over a continuous memory area.
  529.     In order to confuse things a little, TECO-C has one addition
  530. to the basic edit buffer gap management.  Following the end of the
  531. edit buffer (EBfEnd) is the current input stream buffer.  Since file
  532. input commands always cause text to be appended to the end of the edit
  533. buffer, this is natural.  Thus, no input buffer is needed: text is
  534. input directly into the edit buffer.  This makes the code a little
  535. confusing, but it avoids the problem of having an input buffer.  When
  536. you have an input buffer, you have to deal with the question of how
  537. large the buffer should be and what to do with it when it's too small.
  538. this scheme is fast and and saves some memory. (see File Input)
  539.  
  540. .HEADER LEVEL 2 Q-registers
  541.     Q-registers have two parts: a numeric part and a text part.
  542. Each q-register is represented by a structure containing three fields:
  543. one to hold the numeric part and two to point to the beginning and end
  544. of the memory holding the text part.  If the text part of the
  545. q-register is empty, then the pointer to the beginning of the text is
  546. NULL.
  547.     There are 36 global q-registers, one for each letter of the
  548. alphabet and 1 for each digit from 0 to 9.  These q-registers are
  549. accessible from any macro level.  There are 36 local q-registers for
  550. each macro level.  The names for local q-registers are preceded by a
  551. period.  Thus the command "1xa" inserts a line into global q-register
  552. "a", while the command "1x.a" inserts a line into local q-register
  553. ".a".  Storage for the data structure defining local q-registers is
  554. not allocated until a local q-register is first used.  This saves
  555. space and time, because local q-registers are rarely used, and doing
  556. things this way avoids allocating and freeing memory every time a
  557. macro is executed.
  558.  
  559. .HEADER LEVEL 1 Stacks
  560.  
  561. .HEADER LEVEL 2 Expression Stack
  562.     An expression stack is used to parse TECO's expressions.
  563. Consider the command string QA+50=$$.  When the command string is
  564. executed, the value of QA is pushed on the expression stack, then the
  565. operator "+" is pushed on the expression stack, and then the value
  566. "50" is pushed on the expression stack.  Whenever a full expression
  567. that can be reduced is on the expression stack, it is reduced.  For
  568. the above example, the stack is reduced when the value "50" is pushed.
  569.     The expression stack is implemented in the following variables:
  570. .LITERAL
  571.  
  572.     EStack    the stack itself,  containing saved operators and operands
  573.     EStTop    index of the top element in EStack
  574.     EStBot    index of the current "bottom" of the stack in EStack
  575. .END LITERAL
  576.      The "bottom" of the expression stack can change because an
  577. expression can include a macro invocation.  For example, the command
  578. QA+M3=$$ causes the value of "QA" to be pushed on the expression
  579. stack, then the "+" is pushed, and then the macro contained in
  580. q-register 3 is executed.  The macro in q-register 3 returns a value
  581. to be used in the expression.  When the macro is entered, a new
  582. expression stack "bottom" is established.  This allows the macro to
  583. have a "local" expression stack bottom while maintaining the stack
  584. outside the macro.
  585.  
  586. .HEADER LEVEL 2 Loop Stack
  587.     The loop stack contains the loop count and the address of the
  588. first command in the loop.  For example, in the command 5<FSMP$mt$>$$,
  589. the loop stack contains the loop count (5) and the address of the
  590. first command in the loop (F).  Whenever the end-of-loop character (>)
  591. is encountered, the loop count is decremented.  If the loop count is
  592. still greater than zero after it has been decremented, then the
  593. command string pointer is reset to point to the first character in the
  594. loop (F).
  595.     The loop stack is implemented in the following variables:
  596. .LITERAL
  597.  
  598.     LStack    the stack itself,  containing saved counts and addresses
  599.     LStTop    index of the top element in LStack
  600.     LStBot    index of the current "bottom" of the stack in LStack
  601. .END LITERAL
  602.     The loop stack needs a "floating" bottom for the same reason
  603. that the expression stack needs one: macros.  Consider the command
  604. string 4<Smp$M7$>$$.  When the "<" in is encountered, the loop count
  605. (4) and the address of the first character in the loop (S) are placed
  606. on the loop stack.  Command execution continues, and the "M7" command
  607. is encountered.  Suppose that q-register 7 contains the erroneous
  608. command string 10>DL>$$.  When the ">" command is encountered in the
  609. macro, TECO expects the loop stack to contain a loop count and an
  610. address for the first character in the loop.  In this example, there
  611. is no matching "<" command in the macro which would have set up the
  612. loop stack.  It would be very bad if TECO were to think that the loop
  613. count was 4 and the first command in the loop was "S".  In this
  614. situation, what TECO should do is generate the error message "BNI >
  615. not in iteration".  In order to implement this, the variable LStBot is
  616. adjusted each time a macro is entered or exited.  LStBot represents
  617. the bottom of the loop stack for the current macro level.
  618.  
  619. .HEADER LEVEL 2 Macro Stack
  620.     The macro stack is used to preserve context each time a macro
  621. is entered.  All important values are pushed onto the stack before a
  622. macro is entered and popped off the stack when the macro is exited.
  623. The macro stack is also used by the EI command, which means it's used
  624. when executing initialization files and mung files.
  625.  
  626. .HEADER LEVEL 1 Help
  627.     This section discusses on-line HELP,  which is available only under
  628. VAX/VMS.
  629.     The HELP command is not documented in the TECO manual
  630. distributed by DEC., even though it is supported in TECO-11 and
  631. TECO-32.  To get help, simply type "HELP" followed by a carriage
  632. return.  HELP is the only TECO command that is not terminated by
  633. double escapes.
  634.     Help in TECOC is different than help in TECO-11.  In TECO-C,
  635. interactive help mode is entered, so that a user can browse through a
  636. help tree, as he can from DCL.  In TECO-C, access is provided to only
  637. two libraries: the library specific to TECO-C (pointed to by logical
  638. name TEC$INIT) and the system help library.  To get help on TECO-C,
  639. just say "HELP", with or without arguments.  To get help from the
  640. system library, say "HELP/S".  I find this easier to use than
  641. TECO-11's syntax.
  642.     The help library for TECO-C is contained in file TECOC.HLB,
  643. which is generated from TECOC.HLP, which is generated from TECOC.RNH.
  644. See file TECOC.RNH for a description of how to do it.  This help
  645. library is far broader than the library for TECO-11, but much of it
  646. has yet to be filled in.
  647.     The help library is also the repository for verbose error
  648. messages, which are displayed when the help flag (EH) is set to 3.
  649. For systems other than VMS, the ZHelp function displays verbose text
  650. contained in static memory (see file ZHELP.C).
  651.  
  652. .HEADER LEVEL 1 File Input
  653.     TECO has an elegant design that allows high speed input.
  654. There are no linked list data structures to keep track of, and most
  655. file input goes directly to the end of the edit buffer.
  656.     TECO-C takes advantage of this by reading normal file input
  657. directly to the end of the edit buffer.  After each input call,
  658. nothing needs to be moved; the pointer to the end of the edit buffer
  659. is simply adjusted to point to the end of the new record.  The pointer
  660. to the end of the edit buffer (EBfEnd) serves two purposes: it points
  661. to the end of the edit buffer and to the beginning of the input
  662. buffer.
  663.     A side effect of this scheme is the sharing of memory between
  664. the edit buffer and the input buffer.  When the edit buffer is empty,
  665. it can be made smaller by shrinking the edit buffer gap in order to
  666. make the input buffer larger.  Obviously, if the edit buffer needs to
  667. be expanded, the input buffer can suffer before more memory is
  668. actually requested from the operating system.  This is easily achieved
  669. by moving the pointer to the "end-of-the-edit-buffer"/
  670. "beginning-of-the-input-buffer".
  671.     This scheme works, but provides no support for the other forms
  672. of file input.  The EP and ER$ commands provide a complete secondary
  673. input stream which can be open at the same time as the primary stream
  674. (two input files at once).  The EI command reads and executes files
  675. containing TECO commands, and is used to execute the initialization
  676. file, if one exists.  The EQq command, if implemented, reads the
  677. entire contents of a file directly into a Q-register.
  678.     A second problem arises: on each of the open files, the
  679. quantum unit of input is not standard.  For A, Y and P commands, a
  680. form feed or end-of-file "terminate" the read.  For n:A commands, form
  681. feed, end-of-line or end-of-file "terminate" each read.  For EI
  682. commands, two escapes or end-of-file "terminate" the read.  The input
  683. code must "save" the portion of an input record following a special
  684. character and yield the saved text when the next command for the file
  685. is executed.
  686.     The scheme used in TECO-C is to read text from the current
  687. input stream directly to the end of the edit buffer.  When the input
  688. stream is switched via a EP or ER$ command, the obvious switching of
  689. file descriptors happens, and any text that's "leftover" from the last
  690. read is explicitly saved elsewhere.  Note that this happens VERY
  691. rarely, so a malloc/free is acceptable.
  692.     For EI and EQq commands, the input memory following the edit
  693. buffer is used as a temporary input buffer.  After the file is read,
  694. the text is copied to a Q-register in the case of EQq and to a
  695. separate buffer in the case of EI.
  696.  
  697. .HEADER LEVEL 1 Video
  698.     As of 18-Feb-1991, TECO-C supports video only under Unix.
  699. The code was written by Mark Henderson, using the CURSES package.
  700. See file VIDEO.TXT for a discussion of how it works.
  701.  
  702. .HEADER LEVEL 1 Portability
  703.     TECO-C was written with portability in mind.  The first
  704. development machine was "minimal": a SAGE IV (68000) running CP/M-68k.
  705. In that environment, there was no "make" utility.
  706.     Initially, the system-independent code (files that don't start
  707. with a "Z") had absolutely no calls to standard C runtime functions.
  708. This was because I had several problems with the "standard" functions
  709. not being "standard" on different machines.  With the onset of ANSI C
  710. I've grown less timid, but the main code still references almost no
  711. standard functions.  This is less of a limitation than you might
  712. think: TECO-C doesn't use null-terminated strings.  It also doesn't
  713. use unions, floating point or bit fields.
  714.  
  715. .HEADER LEVEL 1 Porting to a new environment
  716. .LIST
  717. .LIST ELEMENT
  718. Move the source code to the target machine.
  719. .LIST ELEMENT
  720. Inspect file ZPORT.H.  You need to select the compiler you want the
  721. code compiled for.  For instance, if you are porting to a Unix system,
  722. then fix ZPORT.H so that the unix identifier is defined (it is usually
  723. defined by default by the compiler).  If your compiler is nothing like
  724. anything supported by ZPORT.H, then set the UNKNOWN identifier.
  725. .LIST ELEMENT
  726. Compile and link.  See file AAREADME.TXT for descriptions of how TECO-C
  727. is built in supported environments,  and steal like mad.  The problem
  728. here is that you need a "Z" file for your environment,  containing all
  729. the "Z" functions needed by TECO-C.  The easiest thing to do is copy
  730. ZUNKN.C to your own "Z" file and link against that.  For instance,  if
  731. I ever port TECO-C to a Macintosh,  I'll copy ZUNKN.C to ZMAC.C.
  732. .LIST ELEMENT
  733. Fix things so the compile/link is successful.  If you have compiled
  734. with UNKNOWN set, you should get an executable file that displays a
  735. message and dies when the first system-dependent function is called.
  736. The strategy is to fix that function (often by stealing from the code
  737. for other operating systems), relink and deal with the next
  738. message until you have something that works.  Functions should be
  739. implemented in roughly the following order: ZInit, ZTrmnl, ZExit,
  740. ZDspCh, ZAlloc, ZRaloc, ZFree, ZChin.  This will give you a TECO with
  741. everything but file I/O.  You can run it, add text to the edit buffer,
  742. delete text, search, use expressions and the = sign command (a
  743. calculator).  Then do file input: ZOpInp, ZRdLin, ZIClos.  Then do
  744. file output: ZOpout, ZWrBfr, ZOClos, ZOClDe.  Use the test macros
  745. (*tst*.tec) to test how everything works (see Testing).
  746.  
  747. .END LIST
  748.  
  749. .HEADER LEVEL 1 Testing
  750.     Testing of TECO-C is performed by executing macros.  The
  751. macros are contained in files named TSTxxx.TEC, where XXX is some kind
  752. of indication as to what is tested.  For instance, TSTQR.TEC tests
  753. q-registers.  The test macros do not test all the functions provided
  754. by TECO.  They were originally used to verify that TECO-C performs
  755. exactly the same as TECO-11 under the VMS operating system.  When I
  756. needed to test a chunk of code, I sometimes did it the right way and
  757. wrote a macro.
  758.  
  759. .HEADER LEVEL 1 Debugging
  760.     A debugging system (very ugly, very useful) is imbedded within
  761. the code.  It is conditionally complied into the code by turning on or
  762. off an identifier (DEBUGGING) defined in the TECOC.H file.  When
  763. debugging code is compiled in, you can access it using the _^P
  764. command, which is not used by regular TECO.  The _^P command with no
  765. argument will display help about how to use _^P.
  766.     If you are working under VMS, it sometimes helps to compare
  767. the execution of TECO-C with TECO-11.  Put a test command string into
  768. a file.  Use DEFINE/USER__MODE to redirect the output of TECO-C to a
  769. file and execute the macro with TECO-C.  Then do the same thing with
  770. TECO-11.  Use the DIFFERENCES command to compare the two output files.
  771. They should be 100 percent identical.
  772.